class_name InventorySystem
extends Control

## 背包系统主控制器
## 管理背包界面、物品存储、拖拽交互等核心功能

signal inventory_changed
signal item_used(item_data: ItemData)

@export var grid_size: Vector2i = Vector2i(5, 4)  # 背包网格大小
@export var slot_size: Vector2 = Vector2(50, 50)  # 槽位大小
@export var slot_spacing: int = 5  # 槽位间距

var inventory_slots: Array[InventorySlot] = []
var selected_slot: InventorySlot = null
var available_items: Array[ItemData] = []

@onready var item_grid: GridContainer = $InventoryPanel/ItemGrid
@onready var item_list: VBoxContainer = $InventoryPanel/ItemList
@onready var close_button: Button = $InventoryPanel/CloseButton

func _ready():
	setup_inventory()
	create_sample_items()
	populate_item_list()
	hide()  # 默认隐藏背包

## 设置背包界面
func setup_inventory():
	# 设置网格容器
	item_grid.columns = grid_size.x
	
	# 创建背包槽位
	for i in range(grid_size.x * grid_size.y):
		var slot = create_inventory_slot(i)
		inventory_slots.append(slot)
		item_grid.add_child(slot)

## 创建单个背包槽位
func create_inventory_slot(index: int) -> InventorySlot:
	var slot = InventorySlot.new()
	slot.slot_size = slot_size
	slot.slot_index = index
	slot.slot_clicked.connect(_on_slot_clicked)
	slot.slot_double_clicked.connect(_on_slot_double_clicked)
	slot.item_dropped.connect(_on_item_dropped)
	return slot

## 创建示例物品
func create_sample_items():
	# 创建武器
	var sword = ItemData.new()
	sword.item_name = "铁剑"
	sword.description = "一把锋利的铁制长剑"
	sword.icon_path = "res://icons/sword.svg"
	sword.item_type = ItemData.ItemType.WEAPON
	sword.max_stack_size = 1
	sword.value = 100
	sword.rarity = 2
	available_items.append(sword)
	
	# 创建护甲
	var armor = ItemData.new()
	armor.item_name = "皮甲"
	armor.description = "轻便的皮制护甲"
	armor.icon_path = "res://icons/armor.svg"
	armor.item_type = ItemData.ItemType.ARMOR
	armor.max_stack_size = 1
	armor.value = 80
	armor.rarity = 1
	available_items.append(armor)
	
	# 创建消耗品
	var potion = ItemData.new()
	potion.item_name = "生命药水"
	potion.description = "恢复50点生命值"
	potion.icon_path = "res://icons/potion.svg"
	potion.item_type = ItemData.ItemType.CONSUMABLE
	potion.max_stack_size = 10
	potion.value = 25
	potion.is_consumable = true
	potion.rarity = 1
	available_items.append(potion)
	
	# 创建材料
	var wood = ItemData.new()
	wood.item_name = "木材"
	wood.description = "普通的木材，可用于制作"
	wood.icon_path = "res://icons/wood.svg"
	wood.item_type = ItemData.ItemType.MATERIAL
	wood.max_stack_size = 99
	wood.value = 5
	wood.rarity = 1
	available_items.append(wood)
	
	# 创建稀有物品
	var gem = ItemData.new()
	gem.item_name = "魔法宝石"
	gem.description = "蕴含强大魔力的宝石"
	gem.icon_path = "res://icons/gem.svg"
	gem.item_type = ItemData.ItemType.MATERIAL
	gem.max_stack_size = 5
	gem.value = 500
	gem.rarity = 4
	available_items.append(gem)

## 填充物品列表
func populate_item_list():
	for item in available_items:
		var button = Button.new()
		button.text = item.item_name
		button.custom_minimum_size = Vector2(100, 30)
		button.pressed.connect(_on_item_button_pressed.bind(item))
		item_list.add_child(button)

## 物品按钮点击事件
func _on_item_button_pressed(item: ItemData):
	add_item(item, 1)

## 添加物品到背包
func add_item(item_data: ItemData, count: int = 1) -> bool:
	var remaining_count = count
	
	# 首先尝试添加到已有的相同物品槽位
	for slot in inventory_slots:
		if not slot.is_empty() and slot.item_data == item_data and slot.item_data.can_stack():
			remaining_count = slot.add_item(item_data, remaining_count)
			if remaining_count <= 0:
				inventory_changed.emit()
				return true
	
	# 然后尝试添加到空槽位
	for slot in inventory_slots:
		if slot.is_empty():
			remaining_count = slot.add_item(item_data, remaining_count)
			if remaining_count <= 0:
				inventory_changed.emit()
				return true
	
	# 如果还有剩余，说明背包已满
	if remaining_count > 0:
		print("背包已满，无法添加 ", remaining_count, " 个 ", item_data.item_name)
		return false
	
	inventory_changed.emit()
	return true

## 从背包移除物品
func remove_item(item_data: ItemData, count: int = 1) -> int:
	var removed_count = 0
	
	for slot in inventory_slots:
		if not slot.is_empty() and slot.item_data == item_data:
			var removed = slot.remove_item(count - removed_count)
			removed_count += removed
			if removed_count >= count:
				break
	
	if removed_count > 0:
		inventory_changed.emit()
	
	return removed_count

## 检查是否有指定物品
func has_item(item_data: ItemData, count: int = 1) -> bool:
	var total_count = 0
	
	for slot in inventory_slots:
		if not slot.is_empty() and slot.item_data == item_data:
			total_count += slot.item_count
			if total_count >= count:
				return true
	
	return false

## 获取物品数量
func get_item_count(item_data: ItemData) -> int:
	var total_count = 0
	
	for slot in inventory_slots:
		if not slot.is_empty() and slot.item_data == item_data:
			total_count += slot.item_count
	
	return total_count

## 槽位点击事件
func _on_slot_clicked(slot: InventorySlot):
	# 取消之前的选中状态
	if selected_slot:
		selected_slot.set_selected(false)
	
	# 设置新的选中状态
	if selected_slot == slot:
		selected_slot = null
	else:
		selected_slot = slot
		slot.set_selected(true)

## 槽位双击事件
func _on_slot_double_clicked(slot: InventorySlot):
	# 如果是消耗品，双击使用
	if not slot.is_empty() and slot.item_data.is_consumable:
		use_item(slot)

## 物品拖拽事件
func _on_item_dropped(from_slot: InventorySlot, to_slot: InventorySlot):
	if from_slot == to_slot:
		return
	
	# 如果目标槽位为空，直接移动
	if to_slot.is_empty():
		to_slot.set_item(from_slot.item_data, from_slot.item_count)
		from_slot.clear_slot()
		inventory_changed.emit()
		return
	
	# 如果是相同物品且可以堆叠
	if from_slot.item_data == to_slot.item_data and to_slot.item_data.can_stack():
		var remaining = to_slot.add_item(from_slot.item_data, from_slot.item_count)
		if remaining == 0:
			from_slot.clear_slot()
		else:
			from_slot.item_count = remaining
			from_slot.update_display()
		inventory_changed.emit()
		return
	
	# 否则交换物品
	var temp_data = to_slot.item_data
	var temp_count = to_slot.item_count
	
	to_slot.set_item(from_slot.item_data, from_slot.item_count)
	from_slot.set_item(temp_data, temp_count)
	
	inventory_changed.emit()

## 使用物品
func use_item(slot: InventorySlot):
	if slot.is_empty() or not slot.item_data.is_consumable:
		return
	
	if slot.item_data.use_item():
		slot.remove_item(1)
		item_used.emit(slot.item_data)
		inventory_changed.emit()

## 显示背包
func show_inventory():
	show()

## 隐藏背包
func hide_inventory():
	hide()

## 切换背包显示状态
func toggle_inventory():
	if visible:
		hide_inventory()
	else:
		show_inventory()

## 关闭按钮点击事件
func _on_close_button_pressed():
	hide_inventory()

## 处理输入事件
func _input(event: InputEvent):
	if event.is_action_pressed("toggle_inventory"):
		toggle_inventory()
		get_viewport().set_input_as_handled()
	
	# 丢弃选中物品 (Delete键)
	if event.is_action_pressed("drop_item") and selected_slot and not selected_slot.is_empty():
		drop_selected_item()
		get_viewport().set_input_as_handled()
	
	# 整理背包 (R键)
	if event.is_action_pressed("sort_inventory"):
		sort_inventory()
		get_viewport().set_input_as_handled()

## 获取背包数据（用于保存）
func get_inventory_data() -> Array:
	var data = []
	for slot in inventory_slots:
		if not slot.is_empty():
			data.append({
				"index": slot.slot_index,
				"item_name": slot.item_data.item_name,
				"count": slot.item_count
			})
	return data

## 加载背包数据（用于读取存档）
func load_inventory_data(data: Array):
	# 清空当前背包
	for slot in inventory_slots:
		slot.clear_slot()
	
	# 加载数据
	for item_data in data:
		var index = item_data["index"]
		var item_name = item_data["item_name"]
		var count = item_data["count"]
		
		# 查找对应的物品数据
		for available_item in available_items:
			if available_item.item_name == item_name:
				inventory_slots[index].set_item(available_item, count)
				break

## 丢弃选中物品
func drop_selected_item():
	if not selected_slot or selected_slot.is_empty():
		return
	
	var item_name = selected_slot.item_data.item_name
	var item_count = selected_slot.item_count
	
	# 清空槽位
	selected_slot.clear_slot()
	selected_slot.set_selected(false)
	selected_slot = null
	
	print("丢弃了 ", item_count, " 个 ", item_name)
	inventory_changed.emit()

## 整理背包
func sort_inventory():
	# 收集所有物品数据
	var items_data = []
	for slot in inventory_slots:
		if not slot.is_empty():
			items_data.append({
				"item_data": slot.item_data,
				"count": slot.item_count
			})
	
	# 清空所有槽位
	for slot in inventory_slots:
		slot.clear_slot()
	
	# 取消选中状态
	if selected_slot:
		selected_slot.set_selected(false)
		selected_slot = null
	
	# 按物品类型和稀有度排序
	items_data.sort_custom(_compare_items)
	
	# 重新放置物品，优先堆叠相同物品
	for item_info in items_data:
		add_item(item_info["item_data"], item_info["count"])
	
	print("背包已整理")
	inventory_changed.emit()

## 物品比较函数（用于排序）
func _compare_items(a: Dictionary, b: Dictionary) -> bool:
	var item_a = a["item_data"] as ItemData
	var item_b = b["item_data"] as ItemData
	
	# 首先按物品类型排序
	if item_a.item_type != item_b.item_type:
		return item_a.item_type < item_b.item_type
	
	# 然后按稀有度排序（稀有度高的在前）
	if item_a.rarity != item_b.rarity:
		return item_a.rarity > item_b.rarity
	
	# 最后按名称排序
	return item_a.item_name < item_b.item_name
